package controllers

import (
	"gitee.com/cjf8134/bbs_serve/internal/app/apiserve/services"
	"gitee.com/cjf8134/bbs_serve/internal/pkg/requests"
	"gitee.com/cjf8134/bbs_serve/internal/pkg/utils/responseutil"
	"github.com/gin-contrib/sessions"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type IndexController struct {
	logger  *zap.Logger
	service services.DefaultService
}

func NewIndexController(logger *zap.Logger, s services.DefaultService) *IndexController {
	return &IndexController{
		logger:  logger.With(zap.String("type", "IndexController")),
		service: s,
	}
}

// Captcha   图形验证码
func (pc *IndexController) Captcha(c *gin.Context) {
	idKeyC, base64stringC := pc.service.GetCaptcha()
	responseutil.SusJson(c, "success", gin.H{"idKeyC": idKeyC, "base64stringC": base64stringC})
}

// ThreadList   帖子列表
func (pc *IndexController) Email(c *gin.Context) {
	var req requests.Email
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	req.IP = c.ClientIP()
	err := pc.service.Email(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success")
}

// resetPwd   重置密码
func (pc *IndexController) ResetPwd(c *gin.Context) {
	var req requests.ResetPwd
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	err := pc.service.ResetPwd(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success")
}

// ThreadList   帖子列表
func (pc *IndexController) ThreadList(c *gin.Context) {
	var req requests.ThreadList
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	total, list, err := pc.service.ThreadList(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success", gin.H{"thread": list, "total": total})
}

// ThreadList   帖子列表
func (pc *IndexController) ThreadDetail(c *gin.Context) {
	var req requests.ThreadDetail
	if err := c.ShouldBindQuery(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	list, err := pc.service.ThreadDetail(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success", list)
}

// LinkList   帖子列表
func (pc *IndexController) LinkList(c *gin.Context) {
	var req requests.LinkList
	if err := c.ShouldBindQuery(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	list, err := pc.service.LinkList(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success", list)
}

// TestExist   判断对应字段是否存在
func (pc *IndexController) TestExist(c *gin.Context) {
	var req requests.TextExists
	if err := c.ShouldBindQuery(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	exists := pc.service.TestExist(&req)
	responseutil.SusJson(c, "success", exists)
}

// Register 注册
func (pc *IndexController) Register(c *gin.Context) {
	var req requests.Register
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	req.Ip = c.ClientIP()
	err := pc.service.Register(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success")
}

// Login 登陆
func (pc *IndexController) Login(c *gin.Context) {
	var req requests.Login
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	req.Ip = c.ClientIP()
	user, err := pc.service.Login(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success", user)
}

// Login 登陆
func (pc *IndexController) User(c *gin.Context) {
	sess := sessions.Default(c)
	userID := sess.Get("userID").(int)
	user, err := pc.service.GetUser(userID)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success", user)
}

// Comment 回复
func (pc *IndexController) Comment(c *gin.Context) {
	var req requests.Comment
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	sess := sessions.Default(c)
	req.Username = sess.Get("username").(string)
	req.Avatar = sess.Get("avatar").(string)
	err := pc.service.Comment(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success")
}

// Comment 回复
func (pc *IndexController) Thread(c *gin.Context) {
	var req requests.Thread
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	sess := sessions.Default(c)
	req.Username = sess.Get("username").(string)
	req.Avatar = sess.Get("avatar").(string)
	err := pc.service.Thread(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success")
}

// Zan 点赞
func (pc *IndexController) Zan(c *gin.Context) {
	var req requests.CommentZan
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	sess := sessions.Default(c)
	req.UserID = sess.Get("userID").(int)
	err := pc.service.CommentZan(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success")
}

// Search 搜索
func (pc *IndexController) Search(c *gin.Context) {
	var req requests.ThreadSearch
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	total, list, err := pc.service.Search(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success", gin.H{"thread": list, "total": total})
}

func (pc *IndexController) UserTotal(c *gin.Context) {
	userTotal, threadTotal, commentTotal := pc.service.UserTotal()
	responseutil.SusJson(c, "success", gin.H{"user_total": userTotal, "thread_total": threadTotal, "comment_total": commentTotal})
}

// CommentList 回复列表
func (pc *IndexController) CommentList(c *gin.Context) {
	var req requests.CommentList
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	list, err := pc.service.CommentList(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success", list)
}

// ScoreSort 积分列表
func (pc *IndexController) ScoreSort(c *gin.Context) {
	var req requests.ScoreSort
	if err := c.ShouldBindQuery(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	list, err := pc.service.ScoreSort(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success", list)
}

// Upload 文件上次
func (pc *IndexController) Upload(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		responseutil.FailJson(c, err.Error())
	}
	result, err := pc.service.FileUpload(file)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		return
	}
	responseutil.SusJson(c, "success", result)
}

func (pc *IndexController) UserThread(c *gin.Context) {
	var req requests.UserThread
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	sess := sessions.Default(c)
	req.Username = sess.Get("username").(string)
	total, list, err := pc.service.UserThread(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success", gin.H{"thread": list, "total": total})
}
func (pc *IndexController) Avatar(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		responseutil.FailJson(c, err.Error())
	}
	result, err := pc.service.FileUpload(file)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		return
	}
	sess := sessions.Default(c)
	userID := sess.Get("userID").(int)
	user, err := pc.service.Avatar(result, userID)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success", user)
}

// Pwd  修改密码
func (pc *IndexController) Pwd(c *gin.Context) {
	var req requests.Pwd
	if err := c.ShouldBindJSON(&req); err != nil {
		pc.logger.Error("request params error = ", zap.Error(err))
		responseutil.FailJson(c, "request params error")
		return
	}
	sess := sessions.Default(c)
	req.UserID = sess.Get("userID").(int)
	err := pc.service.Pwd(&req)
	if err != nil {
		pc.logger.Error("error", zap.Error(err))
		responseutil.FailJson(c, err.Error())
		return
	}
	responseutil.SusJson(c, "success")
}
